#include "pch.h"

#include "ComputerEngine.h"

using namespace Platform;

namespace CXEngineWrapper
{
	// converts managed checkers board to bitboard
	BitBoard MakeBitBoard(const Array<Coordinate^>^ board)
	{
		int boardSize = (int)floor(sqrt(board->Length));

		BitBoard bb;
		memset(&bb, 0, sizeof(BitBoard));

		for(int row = 0; row < boardSize; row++)
		{
			for(int col = 0; col < boardSize; col++)
			{
				int index = row * boardSize + col;
				if(board[index]->FigureType != eFigureType::Nothing)
				{

					int shift = row * 4;
					if(row % 2 == 0)
						shift += col / 2;
					else
						shift += (col - 1) / 2;

					switch(board[index]->FigureType)
					{
					case eFigureType::WhiteMan:
						bb.wm |= 1 << shift;
						break;
					case eFigureType::BlackMan:
						bb.bm |= 1 << shift;
						break;
					case eFigureType::WhiteKing:
						bb.wk |= 1 << shift;
						break;
					case eFigureType::BlackKing:
						bb.bk |= 1 << shift;
						break;
					}
				}
			}
		}

		return bb;
	}

	// converts managed checkers board to bitboard - 64-bit version
	BitBoard64 MakeBitBoard64(const Array<Coordinate^>^ board)
	{
		int boardSize = (int)floor(sqrt(board->Length));

		BitBoard64 bb;
		memset(&bb, 0, sizeof(BitBoard64));

		for(int row = 0; row < boardSize; row++)
		{
			for(int col = 0; col < boardSize; col++)
			{
				int index = row * boardSize + col;
				if(board[index]->FigureType != eFigureType::Nothing)
				{

					int shift = row * 4;
					if(row % 2 == 0)
						shift += col / 2;
					else
						shift += (col - 1) / 2;

					switch(board[index]->FigureType)
					{
					case eFigureType::WhiteMan:
						bb.wm |= 1ull << shift;
						break;
					case eFigureType::BlackMan:
						bb.bm |= 1ull << shift;
						break;
					case eFigureType::WhiteKing:
						bb.wk |= 1ull << shift;
						break;
					case eFigureType::BlackKing:
						bb.bk |= 1ull << shift;
						break;
					}
				}
			}
		}

		return bb;
	}



	// convert engine bitboard to mananged output bitboard
	OutputBitBoard^ ConvertMoveBitBoard(BitBoard bb)
	{
		OutputBitBoard^ obb = ref new OutputBitBoard();

		obb->wm = bb.wm;
		obb->bm = bb.bm;
		obb->wk = bb.wk;
		obb->bk = bb.bk;
		
		return obb;
	}

	OutputBitBoard^ ConvertMoveBitBoard64(BitBoard64 bb)
	{
		OutputBitBoard^ obb = ref new OutputBitBoard();

		obb->wm = bb.wm;
		obb->bm = bb.bm;
		obb->wk = bb.wk;
		obb->bk = bb.bk;
		
		return obb;
	}


	// convert output managed bitboard to engine bitboard
	BitBoard ConvertFromOutputBitBoard(OutputBitBoard^ obb)
	{
		BitBoard bb;

		bb.wm = (uint32)obb->wm;
		bb.bm = (uint32)obb->bm;
		bb.wk = (uint32)obb->wk;
		bb.bk = (uint32)obb->bk;

		return bb;
	}

	BitBoard64 ConvertFromOutputBitBoard64(OutputBitBoard^ obb)
	{
		BitBoard64 bb;

		bb.wm = obb->wm;
		bb.bm = obb->bm;
		bb.wk = obb->wk;
		bb.bk = obb->bk;

		return bb;
	}


}

